package com.medranocg.gd

import org.hibernate.type.StandardBasicTypes

import grails.gorm.DetachedCriteria
import org.apache.commons.logging.LogFactory
import static org.springframework.http.HttpStatus.*

import com.medranocg.gd.alfresco.Utils

class DocumentController {

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
    static final log = LogFactory.getLog(this)
    def documentService
   
    def index() { }

    def createNew() {
		session.gd = params.gd
        if (params.fileName == null) {
            listPendingFiles()
        } else {
            def model = [fileName: params.fileName]
            create("ALTA", model)
        }
    }

    def createUpdate() {
        create("MODIFICACION", [:])
    }

    private def create(fileTypeShortName, model) {
        def documentTypes = DocumentType.createCriteria().list {
            fileTypes { 
                eq 'shortName', fileTypeShortName 
            }
            order 'versionable', 'desc'
            order 'name'
        }
        model['now'] = new Date()
        model['documentTypes'] = documentTypes
        render(view: 'create', model: model) 
    }

    private def listPendingFiles() {
        def baseDir = grailsApplication.config.grupoDocumental2.repositoryPath
        def docHandler = new DocumentFilesHandler(baseDir)
        def files = docHandler.listFiles()
        def model = [files: files]
        render(view: 'fileList', model: model)        
    }

	def save() {
		flash.errors = []

		if (!params.customerId)
			flash.errors += ['Debe ingresar un cliente.']

		if (!params.box)
			flash.errors += ['Debe ingresar una caja.']
		
		if (flash.errors) {
			create("ALTA", [fileName: params.fileName])
			return
		}

        def baseDir = grailsApplication.config.grupoDocumental2.repositoryPath
        def docHandler = new DocumentFilesHandler(baseDir)
        def documentFile = docHandler.getFile(params.fileName)
        
        def expirationDate = params.date('expirationDate')
        def loggedInUser = session.usuario.userName
        def now = new Date()

        def tags = params.tags ? params.tags : ""
        def notes = params.notes ? params.notes : ""
        def newVersionConfirmed = params.newVersionConfirmed?.toLowerCase() == 'true'

        if (!newVersionConfirmed && 
            documentService.needsNewVersionConfirmation(
                                params.customerId, params.documentType)) {
            def model = params
            model['needsNewVersionConfirmation'] = true
            return create("ALTA", model)
        }

        try {
            def result = documentService.createDocument(
                                       params.customerId, 
                                       params.box, 
                                       params.documentType, 
                                       expirationDate, 
                                       tags, 
                                       documentFile,
                                       loggedInUser,
                                       now, 
                                       params.notes)
        
            flash.success = result.success
            if (result.success) {
                saveLastValues(params)
                flash.message = "Documento guardado exitosamente: ${documentFile.getOriginalFilename()}"
                flash.document = result.document
            } else {
                flash.message = "Se produjo un error: el documento no pudo guardarse"
            }
        } catch (RuntimeException e) {
            flash.sucess = false
            flash.message = e.toString()
            log.fatal("Error guardando el documento", e) 
        }
        redirect(action: 'showSaved')
    }

    private def badRequest(message) {
        flash.success = false
        flash.message = message
        render(status: BAD_REQUEST, view: 'create')
        redirect(action: 'createNew')
    }

    private def saveLastValues(params) {
        
        if (!session.last) {
            session.last = [:]
        }

        session.last.customer = [:]
        session.last.customer.customerId = params.customerId
        session.last.customer.description = params.customerDescription
        session.last.box = params.box
        
    }

    def openFile() {

        // render(file: new File(absolutePath), fileName: "book.pdf")
        def fileName = params.fileName        
        def baseDir = grailsApplication.config.grupoDocumental2.repositoryPath
        def docHandler = new DocumentFilesHandler(baseDir)
        def stream = docHandler.getFile(fileName).getInputStream()
        response.setContentType("application/pdf")
        response.outputStream << stream 

    }

    def openFileFromRepository(Document documentInstance) {

        def loggedInUser = session.usuario.userName
        def alfClient = new Utils(grailsApplication.config.alfresco)
                                .getClient(loggedInUser: loggedInUser)

        alfClient.getContent(documentInstance, response.outputStream)

    }

    def showSaved() {
		session.gd = params.gd
        def loggedInUser = session.usuario.userName
        def documents = Document.where {
            createdByUserName == loggedInUser
			deleteDate == null
        }.list(sort: 'createdDate', 
               order: 'desc', 
               max: 50)
        def model = [:]
        model.documents = documents
        model
        
    }

    def show(Document documentInstance) {

        if (documentInstance == null) {
            notFound()
            return
        }

        def model = [document: documentInstance]

        render(view: 'show', model: model) 

    }

    def cantidad() {

        def itemsPerPage = 10
        def offset = params.offset ? params.offset as Integer : 0
        def dateFrom = params.date('dateFrom')
        def dateTo = params.date('dateTo')
        def reportType = params.reportType ?: 'byCustomer'

        def getResult = {
            if (reportType == 'byCustomer') {
                return documentService.countByCustomer(params.customerId,
                                                     params.cajaId,
                                                     dateFrom,
                                                     dateTo,   
                                                     offset,
                                                     itemsPerPage)
            } else if (reportType == 'byBox') {
                return documentService.countByBox(params.customerId,
                                                     params.cajaId,
                                                     dateFrom,
                                                     dateTo,   
                                                     offset,
                                                     itemsPerPage)

            } else if (reportType == 'byDate') {
                return documentService.countByDate(params.customerId,
                                                     params.cajaId,
                                                     dateFrom,
                                                     dateTo,   
                                                     offset,
                                                     itemsPerPage)

            }
        }
        
        def model = [reportType: reportType]
        if (params.reportType) {
            def result = getResult()
            model += [items: result.items,
                     offset: result.offset,
                     itemsPerPage: itemsPerPage,
                     totalItems: result.totalItems]
        }
        render(view: 'cantidadDocumentos', model: model)
    }    

    def actualizacionesPorLegajo() {

        def itemsPerPage = 10
        def offset = params.offset ? params.offset as Integer : 0
        def dateFrom = params.date('dateFrom')
        def dateTo = params.date('dateTo')
        
        def model = [:]
        if (params._action == 'search') { 
            def result = documentService.versionsByFile(params.customerId,
                                                    params.cajaId,
                                                    dateFrom,
                                                    dateTo,
                                                    offset,
                                                    itemsPerPage)
            def groupedResults = result.items.groupBy([{ it.customer.idPersona },
                                                       { it.documentType.id }])
            def groups = result.items.collect { 
                    [ it.customer.idPersona, it.documentType.id ] }.unique()
    
            model += [items: result.items,
                      offset: result.offset,
                      groupedResults: groupedResults,
                      groups: groups,  
                      itemsPerPage: itemsPerPage,
                      totalItems: result.totalItems]
        }
        render(view: 'actualizacionesPorLegajo', model: model)
    }    


    protected void notFound() {
        request.withFormat {
            form {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'documentInstance.label', default: 'Document'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }


}
